package cron

import (
	"bigdevops/src/config"
	"bigdevops/src/models"
	"context"
	"github.com/prometheus/alertmanager/template"
	"k8s.io/apimachinery/pkg/util/wait"
	"sync"
	"time"
)

type AlertCache struct {
	AlertReceiveQ chan template.Alert
	Sc            *config.AlertWebhookConfig
	// 为什么需要map ：alert并发会很高：需要 根据alert_send_group id去拿到  models.MonitorSendGroup
	// 如果 每次都查询数据库 ：db打的很高：本地cache
	// 优点： 很好的保护数据库，获取数据 在内存中 的延迟 比 查询db的网络io 要低很多
	// 缺点： 如果sg 信息更新了：我们需要等到下一个renewMap的周期才可以获取到
	SendGroupMap         map[string]*models.MonitorSendGroup
	UserMap              map[uint]*models.User
	OndutyGroupMap       map[uint]*models.MonitorOndutyGroup
	RuleMap              map[string]*models.MonitorAlertRule
	cacheHasSynced       chan struct{}
	StartFinishRenew     bool
	SendGroupLock        sync.RWMutex
	UserLock             sync.RWMutex
	RuleLock             sync.RWMutex
	OndutyGroupLock      sync.RWMutex
	SiLiaoRobotToken     string
	SiLiaoRobotTokenLock sync.RWMutex
}

func NewAlertCache(sc *config.AlertWebhookConfig, alertReceiveQ chan template.Alert, cacheHasSynced chan struct{}) *AlertCache {

	ac := &AlertCache{
		AlertReceiveQ:  alertReceiveQ,
		Sc:             sc,
		cacheHasSynced: cacheHasSynced,
		SendGroupMap:   make(map[string]*models.MonitorSendGroup),
		UserMap:        make(map[uint]*models.User),
		OndutyGroupMap: make(map[uint]*models.MonitorOndutyGroup),
		RuleMap:        make(map[string]*models.MonitorAlertRule),
	}
	return ac
}

// 缓存map 刷新管理器
func (ac *AlertCache) RenewMapManager(ctx context.Context) error {
	go wait.UntilWithContext(ctx, ac.RenewMapSendGroup, time.Duration(ac.Sc.CommonMapRenewIntervalSeconds)*time.Second)
	go wait.UntilWithContext(ctx, ac.RenewMapUser, time.Duration(ac.Sc.CommonMapRenewIntervalSeconds)*time.Second)
	go wait.UntilWithContext(ctx, ac.RenewMapOndutyGroup, time.Duration(ac.Sc.CommonMapRenewIntervalSeconds)*time.Second)
	go wait.UntilWithContext(ctx, ac.RenewMapRule, time.Duration(ac.Sc.CommonMapRenewIntervalSeconds)*time.Second)
	go wait.UntilWithContext(ctx, ac.RefreshSiLiaoRebotToken, 5*time.Minute)
	<-ctx.Done()
	ac.Sc.Logger.Info("RenewMapManager 收到其他任务退出信号 退出")
	return nil
}
